1. Field
The invention relates to selective optimization of portions of a computer program based on observations or predictions of program execution behavior, in particular, to techniques for dynamically optimizing selected portions of a computer program based on identification of a break-even point.
2. Description of the Related Art
Typically, software programmers generate software programs by writing language statements in a human-readable language to create a file containing source statements or source code. In order to run the file, the source statements must be prepared for execution by being made machine-readable. For example, appropriate language compiler is typically run on file containing the source statements. A compiler is a special program that processes statements written in a particular programming or human-readable language and turns them into machine-readable language or code that is usable by a computer's processing unit. When executing or running, the compiler operates on the human-readable program by first parsing or analyzing all of the language statements and then, in one or more successive stages or passes, builds the output code. Traditionally, the output of the compilation has been called object code or sometimes an object module. The object code is machine code that a processing unit can process or execute one instruction at a time.
The Java™ programming language, a language used in object-oriented programming, has popularized the possibility of compiling output (e.g., “bytecode”) that can run on any computer system platform for which a Java virtual machine or bytecode interpreter is provided to convert the bytecode into instructions that can be executed by the actual hardware of the platform. A bytecode interpreter, or simply “interpreter,” will interpret the bytecode one instruction at a time for execution by the hardware. Alternatively, a Java just-in-time (“JIT”) compiler (e.g., a second compiler) at the particular system platform compiles the bytecode into the particular system code as though the program had been compiled initially on that platform. Although recompiling a bytecode often takes more time than interpreting the bytecode, once the code has been recompiled by the JIT compiler it will usually run more quickly on the hardware platform. Thus, an interpreter favors startup over execution efficiency while a compiler slows start-up time but executes programs faster. Notwithstanding, a typical JIT compiles all code that is executed, and hence must attain compilation speed by sacrificing code quality. Thus, source code may be compiled into bytecode which is readable by a Java virtual machine, and the bytecode may in turn be recompiled or interpreted for execution by the actual hardware.
The Java programming language has stimulated work on high performance implementations that dynamically compile or optimize frequently executed portions of programs. The common practice of compiling everything that executes even one time can squander compilation time. Systems that deviate from this practice typically rely on ad hoc heuristics. A reasoned and effective set of heuristics is desirable to optimize the effect of such dynamic compilation, so that time is spent optimally compiling program portions that are frequently executed and not wasted compiling infrequently used program portions.